// Copyright (c) 2025 Yao Yu
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

use xmas_elf::{
    ElfFile, 
    header,
};
use crate::arch::arch_right;
use core::mem;
use ostd::prelude::println;
// use log::debug;

pub fn check_elf_header(data: &[u8]) -> Result<(), &'static str>{
    println!("sizeof={:?}, alignof={:?}",mem::size_of::<xmas_elf::header::HeaderPt1>(), mem::align_of::<xmas_elf::header::HeaderPt1>());
    let elf = ElfFile::new(&data).map_err(|_| "Failed to parse ELF file")?;
    header::sanity_check(&elf)?;

    // pt1 part
    // only support 64bit programs
    check!(elf.header.pt1.class() != header::Class::SixtyFour,
        "Only 64-bit ELF files are supported");
    // little-endian only
    check!(elf.header.pt1.data() != header::Data::LittleEndian,
        "Only little-endian ELF files are supported");
    // current version(1) only
    check!(elf.header.pt1.version() != header::Version::Current, 
        "Only current ELF version is supported");
    // SystemV or Linux OS/ABI only
    let abi = elf.header.pt1.os_abi();
    check!(abi != header::OsAbi::SystemV || abi != header::OsAbi::Linux, 
            "Only SystemV or Linux OS/ABI is supported");
    
    // pt2 part
    // executable only
    check!(elf.header.pt2.type_().as_type() != header::Type::Executable, 
        "Only executable ELF files are supported");
    // ISA check
    check!(arch_right(elf.header.pt2.machine().as_machine()), "arch is dismatch");
    // TODO: check more properties of ELF file


    Ok(())
}

// get entry point from ELF header
pub fn get_entry_point(data: &[u8]) -> Result<usize, &'static str> {
    let head = xmas_elf::header::parse_header(&data).map_err(|_| "Failed to parse header")?;
    let entry_point = head.pt2.entry_point();
    Ok(entry_point.try_into().unwrap())
}